using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Umdf.SideShow.Contents;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace Umdf.SideShow
{
    [Flags]
    public enum CachePolicy
    {
        KeepNewest = 0,
        KeepOldest = 1,
        KeepFrequentlyAccessed = 2,
        KeepRecentlyAccessed = 4
    }

    public class SideShowApplication : SideShowObject
    {
        private Guid _id;
        private string _name;
        private Image _largeIcon;
        private Image _mediumIcon;
        private Image _smallIcon;
        private CachePolicy _cachePolicy;
        private bool _onlineOnly;
        private List<SideShowNotification> _notifications;
        private SideShowDriver _driver;
        private Dictionary<Guid, SideShowEndpoint> _endpoints;

        
        public SideShowApplication(BinaryReader reader)
        {
            
            DeserializeObject(reader);
        }

        public SideShowApplication(SideShowDriver driver, Guid id, string name, CachePolicy cachePolicy, bool onlineOnly, Image smallIcon, Image mediumIcon, Image largeIcon)
        {
            _driver = driver;
            _id = id;
            _name = name;
            _cachePolicy = cachePolicy;
            _onlineOnly = onlineOnly;
            _smallIcon = smallIcon;
            _mediumIcon = mediumIcon;
            _largeIcon = largeIcon;
            _endpoints = new Dictionary<Guid, SideShowEndpoint>();
            foreach (Guid epId in driver.SupportedEndpoints)
            {
                _endpoints.Add(epId, new SideShowEndpoint(epId));
            }
            _notifications = new List<SideShowNotification>();
        }

        public Guid Id
        {
            get { return _id; }
        }

        public string Name
        {
            get { return _name; }
        }

        public Image LargeIcon
        {
            get { return _largeIcon; }
        }

        public Image MediumIcon
        {
            get { return _mediumIcon; }
        }

        public Image SmallIcon
        {
            get { return _smallIcon; }
        }

        public CachePolicy CachePolicy
        {
            get { return _cachePolicy; }
        }

        public bool OnlineOnly
        {
            get { return _onlineOnly; }
        }

        public IDictionary<Guid, SideShowEndpoint> Endpoints
        {
            get { return _endpoints; }
        }

        public void AddNotification(SideShowNotification notification)
        {
            _notifications.Add(notification);
        }

        public void RemoveNotification(int notificationId)
        {
            _notifications.RemoveAll(delegate(SideShowNotification n)
            {
                return n.Id == notificationId;
            });
        }

        public void RemoveAllNotifications()
        {
            _notifications.Clear();
        }

        
        protected internal override void SerializeObject(System.IO.BinaryWriter writer)
        {
            base.SerializeObject(writer);
            
            writer.Write(_id.ToByteArray());
            writer.Write(_name);
            using (MemoryStream ms = new MemoryStream())
            {
                Bitmap img = new Bitmap(_largeIcon);
                img.Save(ms, _largeIcon.RawFormat);
                byte[] buf = ms.ToArray();
                writer.Write(buf.Length);
                writer.Write(buf);
            }
            using (MemoryStream ms = new MemoryStream())
            {
                Bitmap img = new Bitmap(_mediumIcon);
                img.Save(ms, _mediumIcon.RawFormat);
                byte[] buf = ms.ToArray();
                writer.Write(buf.Length);
                writer.Write(buf);
            }
            using (MemoryStream ms = new MemoryStream())
            {
                Bitmap img = new Bitmap(_smallIcon);
                img.Save(ms, _smallIcon.RawFormat);
                byte[] buf = ms.ToArray();
                writer.Write(buf.Length);
                writer.Write(buf);
            }
            writer.Write((int)_cachePolicy);
            writer.Write(_onlineOnly);
            writer.Write(_endpoints.Count);
            foreach (KeyValuePair<Guid, SideShowEndpoint> entry in _endpoints)
            {
                entry.Value.SerializeObject(writer);
            }
        }

        protected internal override void DeserializeObject(BinaryReader reader)
        {
            base.DeserializeObject(reader);
            _id = new Guid(reader.ReadBytes(16));
            _name = reader.ReadString();
            int l = reader.ReadInt32();
            byte[] buf = reader.ReadBytes(l);
            using (MemoryStream ms = new MemoryStream(buf))
            {
                _largeIcon = new Bitmap(ms);
            }
            l = reader.ReadInt32();
            buf = reader.ReadBytes(l);
            using (MemoryStream ms = new MemoryStream(buf))
            {
                _mediumIcon = new Bitmap(ms);
            }
            l = reader.ReadInt32();
            buf = reader.ReadBytes(l);
            using (MemoryStream ms = new MemoryStream(buf))
            {
                _smallIcon = new Bitmap(ms);
            }
            _cachePolicy = (CachePolicy)reader.ReadInt32();
            _onlineOnly = reader.ReadBoolean();
            l = reader.ReadInt32();
            _endpoints = new Dictionary<Guid, SideShowEndpoint>();
            for (int i = 0; i < l; i++)
            {
                SideShowEndpoint ep = new SideShowEndpoint(reader);
                _endpoints.Add(ep.Id, ep);
            }
        }


    }
}
